using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace Microsoft.Cryptography
{
    /// <summary>
    /// SignatureDeformatter class which is using the RSAManaged class as asymetric algorithm.
    /// </summary>
    public class RSAManagedSignatureDeformatter : AsymmetricSignatureDeformatter
    {
        private RSABase _rsaKey;
        private string _strOID; //hashAolgorithm

        /// <summary>
        /// Sets the hash algorithm.
        /// </summary>
        /// <param name="strName">
        /// Supported hash algorithms are 
        ///     MD5, 
        ///     SHA1, 
        ///     SHA256, 
        ///     SHA384, 
        ///     SHA512, 
        ///     RIPEMD160
        /// </param>
        public override void SetHashAlgorithm(string strName)
        {
            _strOID = strName;
        }

        /// <summary>
        /// Sets the RSA asymetric algorithm.
        /// </summary>
        /// <param name="key">The RSA asymetric algorithm</param>
        public override void SetKey(AsymmetricAlgorithm key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (!(key is RSA))
            {
                throw new ArgumentException("key must derive from System.Security.Cryptography.RSA");
            }

            object dummy = CryptoConfig.CreateFromName("RSABase");

            if ((dummy == null) || !(dummy is RSABase))
            {
                throw new Exception("The RSA-class configured in machine.config for setting 'RSABase' must derive from Microsoft.Cryptography.RSABase!");
            }

            _rsaKey = (RSABase)dummy;
            _rsaKey.ImportParameters(((RSA)key).ExportParameters(false));
        }

        /// <summary>
        /// Verifies a given singature as byte array.
        /// </summary>
        /// <param name="rgbHash">Hash value as byte array, which is expected to verify the signature.</param>
        /// <param name="rgbSignature">The given signature byte array to verify.</param>
        /// <returns></returns>
        public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
        {
            if (this._strOID == null)
            {
                throw new Exception(ErrorText.MissingOID);
            }
            if (this._rsaKey == null)
            {
                throw new Exception(ErrorText.MissingKey);
            }
            if (rgbHash == null)
            {
                throw new ArgumentNullException("rgbHash");
            }
            if (rgbSignature == null)
            {
                throw new ArgumentNullException("rgbSignature");
            }

            if (_rsaKey is RSABase)
            {
                return ((RSABase)_rsaKey).VerifyHash(rgbHash, _strOID, rgbSignature);
            }

            return false;
        }
    }
}
